﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace System
{
    /// <summary>
    /// 拷贝的对象必须是可被序列化或者反序列化的
    /// </summary>
    public static class ObjectExtention
    {
        /// <summary>
        /// 深拷贝(所有的属性都是全新的引用),
        /// </summary>
        /// <param name="obj">必须是可被序列化或者反序列化的</param>
        /// <returns></returns>
        public static object DeepCopy(this object obj)
        {
            string str = G.Utils.SerializerHelp.JsonSerializer(obj);
            return G.Utils.SerializerHelp.JsonDeserialize(str, obj.GetType());
        }

        /// <summary>
        /// 浅拷贝，只是拷贝属性的引用,不包括字段
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object Copy(this object obj)
        {
            Type type = obj.GetType();
            object target = Activator.CreateInstance(type);
            obj.CopyTo(target);
            return target;
        }

        /// <summary>
        /// 将一个对象的属性全部拷贝到目标对象中
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="target"></param>
        public static void CopyTo(this object obj, object target)
        {
            Type type = obj.GetType();
            foreach (var item in type.GetProperties())
            {
                if (item.CanWrite)
                    item.SetValue(target, item.GetValue(obj, null), null);
            }
        }


        /// <summary>
        /// 将对象的属性转换成对应的字典集合，只转换属性，不转换字段
        /// </summary>
        /// <param name="page"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Dictionary<string, object> ConvertObjectToDictionary(this object obj)
        {
            Type t = obj.GetType();
            var moduleName = t.Module.Name;
            Dictionary<string, object> dic = new Dictionary<string, object>();
            foreach (var dp in t.GetProperties())
            {
                if (dp.CanWrite && dp.CanRead && dp.Module.Name == moduleName)
                {
                    dic[dp.Name] = dp.GetValue(obj, null);
                }
            }
            return dic;
        }
        /// <summary>
        /// 将集合中的键值对拷贝到对象中
        /// </summary>
        /// <param name="target"></param>
        /// <param name="dic"></param>
        public static void ConvertDictionaryToObject(this object target, Dictionary<string, object> dic)
        {
            Type t = target.GetType();
            var moduleName = t.Module.Name;
            foreach (var dp in t.GetProperties())
            {
                if (dp.CanWrite && dp.CanRead && dp.Module.Name == moduleName && dic.ContainsKey(dp.Name))
                {
                    dp.SetValue(target, dic[dp.Name], null);
                }
            }
        }
        /// <summary>
        /// 将集合转换成对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dic"></param>
        /// <returns></returns>
        public static T ConvertDictionaryToObject<T>(Dictionary<string, object> dic) where T : class
        {
            T obj = Activator.CreateInstance<T>();
            ConvertDictionaryToObject(obj, dic);
            return obj;
        }
    }
}
